package com.example.testcamara;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.LocaleList;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;

import androidx.annotation.RequiresApi;
import androidx.core.os.ConfigurationCompat;

import java.util.HashMap;
import java.util.Locale;

/**
 * <a href="https://blog.csdn.net/u012999651/article/details/127059283">...</a>
 */
public class LanguageUtil2 {

    private static final String TAG = "LanguageUtil";

    /**
     * <a href="https://bailongma.yuque.com/czya5g/ru80iy/gs813an0ag36u859">...</a>
     */
    public static final String CN = "zh-Hans";
    public static final String HK = "zh-Hant-HK";
    public static final String TW = "zh-Hant-TW";
    public static final String EN = "en";

    private static final String SP_LANGUAGE = "save_language";

    private static final String KEY_LAN_CODE = "lanCode";

    private static SharedPreferences getLanCodeSp(Context context) {
        return context.getSharedPreferences(SP_LANGUAGE, Context.MODE_PRIVATE);
    }

    public static void setLanCode(Context context, String lanCode) {
        if (TextUtils.isEmpty(lanCode)) {
            return;
        }
        updateConfiguration(context, lanCode);
        getLanCodeSp(context).edit().putString(KEY_LAN_CODE, lanCode).commit();
    }

    public static String getLanCode(Context context) {
        String spLanCode = getLanCodeSp(context).getString(KEY_LAN_CODE, null);
        if (!TextUtils.isEmpty(spLanCode)) {
            return spLanCode;
        }
        return CN;
    }

    /**
     * 默认支持的语言，英语、法语、阿拉伯语
     */
    private static final HashMap<String, Locale> SUPPORT_LANGUAGE = new HashMap<String, Locale>(3) {{
        put(CN, Locale.SIMPLIFIED_CHINESE);
        put(HK, Locale.TRADITIONAL_CHINESE);
        put(TW, Locale.TRADITIONAL_CHINESE);
        put(EN, Locale.ENGLISH);
    }};

    /**
     * 应用多语言切换，重写BaseActivity中的attachBaseContext即可，采用本地SP存储的语言
     * 这里有一点问题，虽然Android N之后updateConfiguration是过时方法，
     * 官方给出使用createConfigurationContext代替，
     * 但是更新ApplicationContext的Local发现无效使用老版本updateConfiguration正常
     *
     * @param context 上下文
     * @return context
     */
    public static Context attachBaseContext(Context context) {
        String language = getLanCode(context);
        Log.e("EEDD", "启动：" + language);
        return attachBaseContext(context, language);
    }

    /**
     * 应用多语言切换，重写BaseActivity中的attachBaseContext即可
     *
     * @param context  上下文
     * @param language 语言
     * @return context
     */
    public static Context attachBaseContext(Context context, String language) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            return createConfigurationContext(context, language);
        } else {
            return updateConfiguration(context, language);
        }
    }

    /**
     * 获取Local,根据language
     *
     * @param language 语言
     * @return Locale
     */
    private static Locale getLanguageLocale(String language) {
        if (SUPPORT_LANGUAGE.containsKey(language)) {
            Log.e("EEDD", "Locale: " + SUPPORT_LANGUAGE.get(language));
            return SUPPORT_LANGUAGE.get(language);
        } else {
            Locale systemLocal = getSystemLocal();
            for (String languageKey : SUPPORT_LANGUAGE.keySet()) {
                Locale locale = SUPPORT_LANGUAGE.get(languageKey);
                if (locale == null) {
                    continue;
                }
                if (TextUtils.equals(locale.getLanguage(), systemLocal.getLanguage())) {
                    return systemLocal;
                }
            }
        }
        return Locale.forLanguageTag(language);
    }

    /**
     * 获取当前的Local，默认英语
     *
     * @param context context
     * @return Locale
     */
    public static Locale getCurrentLocale(Context context) {
        String language = getLanCode(context);
        if (SUPPORT_LANGUAGE.containsKey(language)) {
            return SUPPORT_LANGUAGE.get(language);
        } else {
            Locale systemLocal = getSystemLocal();
            for (String languageKey : SUPPORT_LANGUAGE.keySet()) {
                Locale locale = SUPPORT_LANGUAGE.get(languageKey);
                if (locale == null) {
                    continue;
                }
                if (TextUtils.equals(locale.getLanguage(), systemLocal.getLanguage())) {
                    return systemLocal;
                }
            }
        }
        return Locale.forLanguageTag(language);
    }

    /**
     * 获取系统的Local
     */
    public static Locale getSystemLocal() {
        return ConfigurationCompat.getLocales(Resources.getSystem().getConfiguration()).get(0);
    }

    /**
     * Android 7.1 以下通过 updateConfiguration
     */
    private static Context updateConfiguration(Context context, String language) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        Locale locale = getLanguageLocale(language);
        Log.e("EEDD", "updateConfiguration: " + locale);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // apply locale
            configuration.setLocales(new LocaleList(locale));
        } else {
            // updateConfiguration
            configuration.locale = locale;
            DisplayMetrics dm = resources.getDisplayMetrics();
            resources.updateConfiguration(configuration, dm);
        }
        return context;
    }

    /**
     * Android 7.1以上通过createConfigurationContext
     * N增加了通过config.setLocales去修改多语言
     */
    @RequiresApi(api = Build.VERSION_CODES.N_MR1)
    private static Context createConfigurationContext(Context context, String language) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        Locale locale = getLanguageLocale(language);
        LocaleList localeList = new LocaleList(locale);
        configuration.setLocales(localeList);
        return context.createConfigurationContext(configuration);
    }

    public static void switchLanguage(Activity activity, String language) {
        switchLanguage(language, activity, MainActivity.class);
    }

    /**
     * 切换语言
     *
     * @param language 语言
     * @param activity 当前界面
     * @param cls      跳转的界面
     */
    public static void switchLanguage(String language, Activity activity, Class<?> cls) {
        switchLanguage(language, activity, cls, null);
    }

    /**
     * 切换语言，携带传递数据
     *
     * @param language 语言
     * @param activity 当前界面
     * @param cls      跳转的界面
     */
    public static void switchLanguage(String language, Activity activity, Class<?> cls, Bundle bundle) {
        String spLonCode = getLanCode(activity);
        if (TextUtils.equals(spLonCode, language)) {
            return;
        }
        setLanCode(activity, language);
        Intent intent = new Intent(activity, cls);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
//        activity.startActivity(intent);
        activity.recreate();
//        activity.finish();
    }

    /**
     * 获取新语言的 Context,修复了androidx.appcompat 1.2.0的问题，当前版本是1.0.0
     */
    public static Context getNewLocalContext(Context newBase) {
        return attachBaseContext(newBase);
    }

    /**
     * 更新Application的Resource local，应用不重启的情况才调用，因为部分会用到application中的context
     * 切记不能走新api createConfigurationContext，亲测
     *
     * @param context     context
     * @param newLanguage newLanguage
     */
    public static void updateApplicationLocale(Context context, String newLanguage) {
        Resources resources = context.getResources();
        Configuration configuration = resources.getConfiguration();
        Locale locale = getLanguageLocale(newLanguage);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // apply locale
            configuration.setLocales(new LocaleList(locale));
        } else {
            configuration.setLocale(locale);
        }
        DisplayMetrics dm = resources.getDisplayMetrics();
        resources.updateConfiguration(configuration, dm);
    }
}
